<template>
  <div
    class="query-page-con flex-column"
    :class="[{ 'query-page-height': !height }]"
    :style="{ height: height }"
  >
    <page-title v-if="title" :has-line="hasLine">{{ props.title }}</page-title>
    <slot name="top-container" />
    <split :no-left="splitNoLeft" :size="splitSize">
      <template #split-left>
        <slot name="split-left"></slot>
      </template>
      <template #split-right>
        <query-form
          v-if="formRenderKeys.length"
          ref="compQueryForm"
          :component-config="formComponentConfig"
          :render-config="formRenderConfig"
          :render-keys="formRenderKeys"
          :has-empty-value="formHasEmptyValue"
          @search="searchHandle"
          @reset="resetHandle"
        />
        <slot name="header-ext-container" />
        <table-container
          v-model:columns="columns"
          class="flex-1"
          :loading="loading"
          :all-columns="allColumns"
          @refresh="refresh"
        >
          <template #container-side>
            <slot name="container-side" />
          </template>
          <standard-table
            ref="compStandardTable"
            v-model:selectedKeys="nowSelectedKeys"
            :component-config="tableComponentConfig"
            :render-config="tableRenderConfig"
            :render-keys="tableRenderKeys"
            :loading="loading"
            :data="data"
            :total="total"
            :row-class="rowClass"
            :row-selection-type="rowSelectionType"
            :columns="columns"
            :span-method="spanMethod"
            :row-key="rowKey"
            :bordered="bordered"
            :empty="empty"
            collapse-btn-key="[0].children[0].children"
            @init-columns-end="initColumns"
            @selection-change="selectionChange"
            @page-change="pageChange"
            @page-size-change="pageSizeChange"
            @row-clickdata="rowClickdatachange"
          >
            <template #index="{ rowIndex, record }">
              <slot name="index" :row-index="rowIndex" :record="record" />
            </template>
            <template #table-header>
              <slot name="table-header" />
            </template>
            <template #table-side>
              <slot name="table-side" />
            </template>
            <template
              v-for="item in renderCustomize"
              :key="item.dataIndex"
              #[item.slotName]="{ rowIndex, record }"
            >
              <slot
                :name="item.slotName"
                :row-index="rowIndex"
                :record="record"
              />
            </template>
            <!-- 自定义操作栏 -->
            <template #operate="{ record, rowIndex }">
              <slot name="operate" :record="record" :row-index="rowIndex" />
            </template>
          </standard-table>
        </table-container>
      </template>
    </split>
    <slot name="bottom-container" />
  </div>
</template>

<script lang="ts" setup>
  import lodash from 'lodash';
  import { computed, defineProps, onMounted, PropType, ref, watch } from 'vue';
  import queryForm from '@/common/components/query-form/index.vue';
  import TableContainer from '@/common/components/table-container/index.vue';
  import StandardTable from '@/common/components/standard-table/index.vue';
  import split from '@/common/components/split/index.vue';
  import pageTitle from '@/common/components/title/page-title.vue';
  import emitter from '@/common/hooks/bus';

  type RowSelectionType = 'checkbox' | 'radio' | '';

  const props = defineProps({
    title: {
      type: String,
      default: '',
    },
    hasLine: {
      type: Boolean,
      default: true,
    },
    formComponentConfig: {
      type: Object,
      default: () => ({}),
    },
    formRenderConfig: {
      type: Object,
      default: () => ({}),
    },
    formRenderKeys: {
      type: Array as PropType<string[]>,
      default: () => [],
    },
    formHasEmptyValue: {
      type: Boolean,
      default: true,
    },
    tableComponentConfig: {
      type: Object,
      default: () => ({}),
    },
    tableRenderConfig: {
      type: Object,
      default: () => ({}),
    },
    tableRenderKeys: {
      type: Array as PropType<string[]>,
      default: () => [],
    },
    loading: {
      type: Boolean,
      default: false,
    },
    data: {
      type: Array,
      default: () => [],
    },
    total: {
      type: Number,
      default: 0,
    },
    selectedKeys: {
      type: Array,
      default: () => [],
    },
    rowKey: {
      type: String,
      default: 'id',
    },
    bordered: {
      type: Boolean,
      default: false,
    },
    rowClass: {
      type: Function,
      default: () => {},
    },
    rowSelectionType: {
      type: String as PropType<RowSelectionType>,
      default: '',
    },
    height: {
      type: String || null,
      default: null,
    },
    spanMethod: {
      type: Function,
      default: () => {},
    },
    empty: {
      type: String,
      default: '',
    },
    splitNoLeft: {
      type: Boolean,
      default: true,
    },
    splitSize: {
      type: Number,
      default: 0.3,
    },
  });
  const emit = defineEmits([
    'queryData',
    'search',
    'reset',
    'refresh',
    'update:selectedKeys',
    'selectionChange',
    'pageSizeChange',
    'pageChange',
    'rowClick',
  ]);
  const compQueryForm = ref<any>(null);
  const compStandardTable = ref<any>(null);
  const columns = ref<object[]>([]);
  const allColumns = ref<object[]>([]);
  const nowSelectedKeys = ref(props.selectedKeys);
  // 重新获取数据
  emitter.on('getTabData', () => {
    emit('queryData', getStatus());
  });
  const initColumns = (data: any[]) => {
    columns.value = lodash.cloneDeep(data);
    allColumns.value = lodash.cloneDeep(data);
  };

  const getStatus = () => {
    return {
      ...compQueryForm.value?.getStatus(),
      ...compStandardTable.value?.getStatus(),
    };
  };

  watch(
    () => props.selectedKeys,
    () => {
      nowSelectedKeys.value = props.selectedKeys;
    }
  );
  const renderCustomize = computed(() => {
    return props.tableRenderKeys
      .filter((key) => {
        return props.tableRenderConfig[key]?.slotName;
      })
      .map((item) => {
        return props.tableRenderConfig[item];
      });
  });
  const queryData = () => {
    emit('queryData', getStatus());
  };

  onMounted(() => {
    queryData();
  });

  const searchHandle = () => {
    compStandardTable.value?.setCurrent(1);
    emit('search', getStatus());
    queryData();
  };
  const resetHandle = () => {
    compStandardTable.value?.setCurrent(1);
    emit('reset', getStatus());
    queryData();
  };
  const setCurrent = (val: any) => {
    compStandardTable.value?.setCurrent(val || 1);
  };
  const refresh = () => {
    emit('refresh', getStatus());
    queryData();
  };
  const selectionChange = (val: string[]) => {
    emit('update:selectedKeys', val);
    emit('selectionChange', val);
  };
  const pageChange = () => {
    emit('pageChange', getStatus());
    queryData();
  };
  const pageSizeChange = () => {
    emit('pageSizeChange', getStatus());
    queryData();
  };
  const rowClickdatachange = (val: any) => {
    emit('rowClick', val);
  };

  const formReset = () => {
    compQueryForm.value?.reset();
  };
  defineExpose({ getStatus, formReset, setCurrent });
</script>

<style lang="less" scoped>
  @import url('../common.less');
  .isScreen {
    .query-page-con {
      padding: 24px;
      height: unset;
    }
  }
  .query-page-con {
    height: 100%;
    border-radius: 8px 8px 8px 8px;
    background-color: #fff;
  }
  .query-page-height {
    height: calc(100vh - 160px);
    min-height: 600px;
  }
  .full-screen.query-page-height {
    bottom: 0 !important;
  }
</style>
